package com.bizmda.bizsip.sink.processor;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONObject;
import com.bizmda.bizsip.common.BizException;
import com.bizmda.bizsip.common.BizResultEnum;
import com.bizmda.bizsip.common.BizUtils;
import com.bizmda.bizsip.config.AbstractSinkConfig;
import com.bizmda.bizsip.converter.Converter;
import com.bizmda.bizsip.sink.connector.Connector;
import com.bizmda.bizsip.sink.api.AbstractSinkService;
import com.bizmda.bizsip.sink.api.SinkBeanInterface;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class SinkBeanSinkProcessor extends AbstractSinkProcessor {
    private SinkBeanInterface sinkBean;

    public SinkBeanSinkProcessor(AbstractSinkConfig sinkConfig) throws BizException {
        super(sinkConfig);
        try {
            if (StrUtil.isEmpty(sinkConfig.getClassName())) {
                throw new BizException(BizResultEnum.SINK_CLASSNAME_NOT_SET);
            }
            Object o = SpringUtil.getBean(Class.forName(sinkConfig.getClassName()));
            if (!(o instanceof SinkBeanInterface)) {
                throw new BizException(BizResultEnum.SINK_JSON_BEAN_SINK_INTERFACE_ERROR,"sink:"+sinkConfig.getId());
            }
            if (o instanceof AbstractSinkService) {
                log.info("Sink服务关联类[{}]继承AbstractSinkService类，自动注入Connector、Converter",
                        o.getClass().getName());
                AbstractSinkService sinkService = (AbstractSinkService) o;
                sinkService.setConnector(this.connector);
                sinkService.setConverter(this.converter);
            }
            this.sinkBean = (SinkBeanInterface) o;
        } catch (ClassNotFoundException e) {
            log.error("Sink服务相关类不存在!", e);
            throw new BizException(BizResultEnum.OTHER_CLASS_NOTFOUND, e);
        }
    }

    @Override
    JSONObject process(JSONObject inMessage) throws BizException {
        log.debug("调用Sink服务[{}](处理器类型sink-bean:{})",
                this.sinkConfig.getId(),this.sinkBean.getClass().getName());
        log.trace("Sink服务请求报文:\n{}", BizUtils.buildJsonLog(inMessage));
        JSONObject outMessage = this.sinkBean.process(inMessage);
        log.trace("Sink服务响应报文:\n{}", BizUtils.buildJsonLog(outMessage));
        return outMessage;
    }
}
